From 9675c990435042236e5814442c62df7b1c2084aa Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 24 Jul 2018 19:50:19 +0200 Subject: [PATCH] render: Make gtk_render_frame() and gtk_render_focus() use the snapshot API This removes a lot of duplicated code. --- gtk/gtkrender.c | 35 ++++- gtk/gtkrenderborder.c | 278 ----------------------------------- gtk/gtkrenderborderprivate.h | 12 -- 3 files changed, 28 insertions(+), 297 deletions(-) diff --git a/gtk/gtkrender.c b/gtk/gtkrender.c index 6272a74ac3..8870518cfa 100644 --- a/gtk/gtkrender.c +++ b/gtk/gtkrender.c @@ -29,7 +29,6 @@ #include "gtkcssshadowsvalueprivate.h" #include "gtkcsstransformvalueprivate.h" #include "gtkhslaprivate.h" -#include "gtkrenderborderprivate.h" #include "gtkrendericonprivate.h" #include "gtkstylecontextprivate.h" @@ -314,15 +313,26 @@ gtk_render_frame (GtkStyleContext *context, gdouble width, gdouble height) { + GtkSnapshot *snapshot; + GskRenderNode *node; + g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (cr != NULL); if (width <= 0 || height <= 0) return; - gtk_css_style_render_border (gtk_style_context_lookup_style (context), - cr, - x, y, width, height); + snapshot = gtk_snapshot_new (); + gtk_snapshot_render_frame (snapshot, context, x, y, width, height); + node = gtk_snapshot_free_to_node (snapshot); + if (node == NULL) + return; + + cairo_save (cr); + gsk_render_node_draw (node, cr); + cairo_restore (cr); + + gsk_render_node_unref (node); } /** @@ -409,15 +419,26 @@ gtk_render_focus (GtkStyleContext *context, gdouble width, gdouble height) { + GtkSnapshot *snapshot; + GskRenderNode *node; + g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (cr != NULL); if (width <= 0 || height <= 0) return; - gtk_css_style_render_outline (gtk_style_context_lookup_style (context), - cr, - x, y, width, height); + snapshot = gtk_snapshot_new (); + gtk_snapshot_render_frame (snapshot, context, x, y, width, height); + node = gtk_snapshot_free_to_node (snapshot); + if (node == NULL) + return; + + cairo_save (cr); + gsk_render_node_draw (node, cr); + cairo_restore (cr); + + gsk_render_node_unref (node); } /** diff --git a/gtk/gtkrenderborder.c b/gtk/gtkrenderborder.c index f8e81253ea..f809e0e215 100644 --- a/gtk/gtkrenderborder.c +++ b/gtk/gtkrenderborder.c @@ -338,74 +338,6 @@ gtk_border_image_render (GtkBorderImage *image, cairo_surface_destroy (surface); } -static void -render_frame_fill (cairo_t *cr, - GskRoundedRect *border_box, - const double border_width[4], - GdkRGBA colors[4], - guint hidden_side) -{ - GskRoundedRect padding_box; - guint i, j; - - padding_box = *border_box; - gsk_rounded_rect_shrink (&padding_box, - border_width[GTK_CSS_TOP], - border_width[GTK_CSS_RIGHT], - border_width[GTK_CSS_BOTTOM], - border_width[GTK_CSS_LEFT]); - - if (hidden_side == 0 && - gdk_rgba_equal (&colors[0], &colors[1]) && - gdk_rgba_equal (&colors[0], &colors[2]) && - gdk_rgba_equal (&colors[0], &colors[3])) - { - gdk_cairo_set_source_rgba (cr, &colors[0]); - - gsk_rounded_rect_path (border_box, cr); - gsk_rounded_rect_path (&padding_box, cr); - cairo_fill (cr); - } - else - { - for (i = 0; i < 4; i++) - { - if (hidden_side & (1 << i)) - continue; - - for (j = 0; j < 4; j++) - { - if (hidden_side & (1 << j)) - continue; - - if (i == j || - (gdk_rgba_equal (&colors[i], &colors[j]))) - { - /* We were already painted when i == j */ - if (i > j) - break; - - if (j == 0) - _gtk_rounded_box_path_top (border_box, &padding_box, cr); - else if (j == 1) - _gtk_rounded_box_path_right (border_box, &padding_box, cr); - else if (j == 2) - _gtk_rounded_box_path_bottom (border_box, &padding_box, cr); - else if (j == 3) - _gtk_rounded_box_path_left (border_box, &padding_box, cr); - } - } - /* We were already painted when i == j */ - if (i > j) - continue; - - gdk_cairo_set_source_rgba (cr, &colors[i]); - - cairo_fill (cr); - } - } -} - static void snapshot_frame_fill (GtkSnapshot *snapshot, const GskRoundedRect *outline, @@ -606,134 +538,6 @@ color_shade (const GdkRGBA *color, _gdk_rgba_init_from_hsla (color_return, &hsla); } -static void -render_border (cairo_t *cr, - GskRoundedRect *border_box, - const double border_width[4], - GdkRGBA colors[4], - GtkBorderStyle border_style[4]) -{ - guint hidden_side = 0; - guint i, j; - - cairo_save (cr); - - cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); - - for (i = 0; i < 4; i++) - { - if (hidden_side & (1 << i)) - continue; - - /* NB: code below divides by this value */ - /* a border smaller than this will not noticably modify - * pixels on screen, and since we don't compare with 0, - * we'll use this value */ - if (border_width[i] < 1.0 / 1024) - continue; - - switch (border_style[i]) - { - case GTK_BORDER_STYLE_NONE: - case GTK_BORDER_STYLE_HIDDEN: - case GTK_BORDER_STYLE_SOLID: - break; - case GTK_BORDER_STYLE_INSET: - if (i == 1 || i == 2) - color_shade (&colors[i], 1.8, &colors[i]); - break; - case GTK_BORDER_STYLE_OUTSET: - if (i == 0 || i == 3) - color_shade (&colors[i], 1.8, &colors[i]); - break; - case GTK_BORDER_STYLE_DOTTED: - case GTK_BORDER_STYLE_DASHED: - { - guint dont_draw = hidden_side; - - for (j = 0; j < 4; j++) - { - if (border_style[j] == border_style[i]) - hidden_side |= (1 << j); - else - dont_draw |= (1 << j); - } - - render_frame_stroke (cr, border_box, border_width, colors, dont_draw, border_style[i]); - } - break; - case GTK_BORDER_STYLE_DOUBLE: - { - GskRoundedRect other_box; - double other_border[4]; - guint dont_draw = hidden_side; - - for (j = 0; j < 4; j++) - { - if (border_style[j] == GTK_BORDER_STYLE_DOUBLE) - hidden_side |= (1 << j); - else - dont_draw |= (1 << j); - - other_border[j] = border_width[j] / 3; - } - - render_frame_fill (cr, border_box, other_border, colors, dont_draw); - - other_box = *border_box; - gsk_rounded_rect_shrink (&other_box, - 2 * other_border[GTK_CSS_TOP], - 2 * other_border[GTK_CSS_RIGHT], - 2 * other_border[GTK_CSS_BOTTOM], - 2 * other_border[GTK_CSS_LEFT]); - render_frame_fill (cr, &other_box, other_border, colors, dont_draw); - } - break; - case GTK_BORDER_STYLE_GROOVE: - case GTK_BORDER_STYLE_RIDGE: - { - GskRoundedRect other_box; - GdkRGBA other_colors[4]; - guint dont_draw = hidden_side; - double other_border[4]; - - for (j = 0; j < 4; j++) - { - other_colors[j] = colors[j]; - if ((j == 0 || j == 3) ^ (border_style[j] == GTK_BORDER_STYLE_RIDGE)) - color_shade (&other_colors[j], 1.8, &other_colors[j]); - else - color_shade (&colors[j], 1.8, &colors[j]); - if (border_style[j] == GTK_BORDER_STYLE_GROOVE || - border_style[j] == GTK_BORDER_STYLE_RIDGE) - hidden_side |= (1 << j); - else - dont_draw |= (1 << j); - other_border[j] = border_width[j] / 2; - } - - render_frame_fill (cr, border_box, other_border, colors, dont_draw); - - other_box = *border_box; - gsk_rounded_rect_shrink (&other_box, - other_border[GTK_CSS_TOP], - other_border[GTK_CSS_RIGHT], - other_border[GTK_CSS_BOTTOM], - other_border[GTK_CSS_LEFT]); - render_frame_fill (cr, &other_box, other_border, other_colors, dont_draw); - } - break; - default: - g_assert_not_reached (); - break; - } - } - - render_frame_fill (cr, border_box, border_width, colors, hidden_side); - - cairo_restore (cr); -} - static void snapshot_border (GtkSnapshot *snapshot, GskRoundedRect *border_box, @@ -856,55 +660,6 @@ snapshot_border (GtkSnapshot *snapshot, snapshot_frame_fill (snapshot, border_box, border_width, colors, hidden_side); } -void -gtk_css_style_render_border (GtkCssStyle *style, - cairo_t *cr, - gdouble x, - gdouble y, - gdouble width, - gdouble height) -{ - GtkBorderImage border_image; - double border_width[4]; - - border_width[0] = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 100); - border_width[1] = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH), 100); - border_width[2] = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH), 100); - border_width[3] = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH), 100); - - if (gtk_border_image_init (&border_image, style)) - { - gtk_border_image_render (&border_image, border_width, cr, x, y, width, height); - } - else - { - GtkBorderStyle border_style[4]; - GskRoundedRect border_box; - GdkRGBA colors[4]; - - /* Optimize the most common case of "This widget has no border" */ - if (border_width[0] == 0 && - border_width[1] == 0 && - border_width[2] == 0 && - border_width[3] == 0) - return; - - border_style[0] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_STYLE)); - border_style[1] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE)); - border_style[2] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE)); - border_style[3] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_LEFT_STYLE)); - - colors[0] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_COLOR)); - colors[1] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR)); - colors[2] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR)); - colors[3] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_LEFT_COLOR)); - - gtk_rounded_boxes_init_for_style (&border_box, NULL, NULL, style, x, y, width, height); - - render_border (cr, &border_box, border_width, colors, border_style); - } -} - void gtk_css_style_snapshot_border (GtkCssStyle *style, GtkSnapshot *snapshot, @@ -1015,39 +770,6 @@ compute_outline_rect (GtkCssStyle *style, } -void -gtk_css_style_render_outline (GtkCssStyle *style, - cairo_t *cr, - gdouble x, - gdouble y, - gdouble width, - gdouble height) -{ - GtkBorderStyle border_style[4]; - GskRoundedRect border_box; - double border_width[4]; - GdkRGBA colors[4]; - - border_style[0] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_STYLE)); - if (border_style[0] != GTK_BORDER_STYLE_NONE) - { - cairo_rectangle_t rect; - - compute_outline_rect (style, x, y, width, height, &rect); - - border_style[1] = border_style[2] = border_style[3] = border_style[0]; - border_width[0] = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_WIDTH), 100); - border_width[3] = border_width[2] = border_width[1] = border_width[0]; - colors[0] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_COLOR)); - colors[3] = colors[2] = colors[1] = colors[0]; - - _gtk_rounded_box_init_rect (&border_box, rect.x, rect.y, rect.width, rect.height); - _gtk_rounded_box_apply_outline_radius_for_style (&border_box, style); - - render_border (cr, &border_box, border_width, colors, border_style); - } -} - void gtk_css_style_snapshot_outline (GtkCssStyle *style, GtkSnapshot *snapshot, diff --git a/gtk/gtkrenderborderprivate.h b/gtk/gtkrenderborderprivate.h index c0bed70854..b8b95a2174 100644 --- a/gtk/gtkrenderborderprivate.h +++ b/gtk/gtkrenderborderprivate.h @@ -29,24 +29,12 @@ G_BEGIN_DECLS -void gtk_css_style_render_border (GtkCssStyle *style, - cairo_t *cr, - gdouble x, - gdouble y, - gdouble width, - gdouble height); void gtk_css_style_snapshot_border (GtkCssStyle *style, GtkSnapshot *snapshot, gdouble width, gdouble height); gboolean gtk_css_style_render_has_outline (GtkCssStyle *style); -void gtk_css_style_render_outline (GtkCssStyle *style, - cairo_t *cr, - gdouble x, - gdouble y, - gdouble width, - gdouble height); void gtk_css_style_snapshot_outline (GtkCssStyle *style, GtkSnapshot *snapshot, gdouble width, -- 2.30.2